package com.zero.client;

import java.awt.EventQueue;
import java.awt.Font;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

import javax.imageio.ImageIO;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;

import com.zero.user.User;
import com.zero.util.Jdbc;

/**
 * 登录窗口页面
 * 
 * @author Zero
 *
 */
public class LoginView extends JFrame {
	private static final long serialVersionUID = 3L;

	private JLabel lblTitle;
	private JLabel lblUserName;
	private JLabel lblPassword;

	private JTextField textFieldUserName;
	private JPasswordField passwordField;

	private JButton btnClear;
	private JButton btnLogin;

	/**
	 * 无参构造
	 */
	public LoginView() {
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setSize(400, 220);
		setLocationRelativeTo(null); // 在屏幕中居中显示
		try {
			setIconImage(ImageIO.read(new File("res/Icon.jpg")));
		} catch (IOException e) {
			SwingUtilities.invokeLater(
					() -> JOptionPane.showMessageDialog(this, "读取图标文件出错", "错误", JOptionPane.ERROR_MESSAGE));
		}
		setTitle("登录");
		setResizable(false);
		init();
		addListener();
		setLayout();
		setVisible(true);
	}

	/**
	 * 有参构造
	 * 
	 * @param name
	 */
	public LoginView(String name) {
		this();
		textFieldUserName.setText(name);
	}

	private void init() {
		lblTitle = new JLabel("欢迎登录");
		lblTitle.setFont(new Font("黑体", Font.BOLD, 16));
		lblTitle.setHorizontalAlignment(SwingConstants.CENTER);

		lblUserName = new JLabel("用户名：");
		lblUserName.setFont(new Font("仿宋", Font.PLAIN, 12));
		lblPassword = new JLabel("密  码：");
		lblPassword.setFont(new Font("仿宋", Font.PLAIN, 12));

		textFieldUserName = new JTextField();
		passwordField = new JPasswordField();

		btnClear = new JButton("清  空");
		btnClear.setFont(new Font("等线", Font.BOLD, 14));
		btnLogin = new JButton("登  录");
		btnLogin.setFont(new Font("等线", Font.BOLD, 14));
	}

	private void addListener() {
		textFieldUserName.addKeyListener(new KeyAdapter() {
			@Override
			public void keyTyped(KeyEvent e) {
				if (e.getKeyChar() == KeyEvent.VK_ENTER) {
					passwordField.grabFocus();
				}
			}
		});

		passwordField.addKeyListener(new KeyAdapter() {
			@Override
			public void keyTyped(KeyEvent e) {
				if (e.getKeyChar() == KeyEvent.VK_ENTER) {
					login();
				}
			}
		});

		btnClear.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				clear();
			}
		});

		btnLogin.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				login();
			}
		});
	}

	private void setLayout() {
		GroupLayout groupLayout = new GroupLayout(getContentPane());
		groupLayout.setHorizontalGroup(groupLayout.createParallelGroup(Alignment.LEADING)
				.addGroup(groupLayout.createSequentialGroup().addContainerGap()
						.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
								.addComponent(lblTitle, GroupLayout.DEFAULT_SIZE, 376, Short.MAX_VALUE)
								.addGroup(Alignment.TRAILING, groupLayout.createSequentialGroup()
										.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
												.addGroup(groupLayout.createSequentialGroup()
														.addComponent(lblPassword, GroupLayout.DEFAULT_SIZE,
																GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
														.addGap(3))
												.addGroup(groupLayout.createSequentialGroup().addComponent(lblUserName)
														.addPreferredGap(ComponentPlacement.RELATED)))
										.addGroup(groupLayout.createParallelGroup(Alignment.TRAILING)
												.addComponent(passwordField, GroupLayout.DEFAULT_SIZE, 298,
														Short.MAX_VALUE)
												.addComponent(textFieldUserName, GroupLayout.DEFAULT_SIZE, 317,
														Short.MAX_VALUE)))
								.addGroup(groupLayout.createSequentialGroup()
										.addComponent(btnClear, GroupLayout.DEFAULT_SIZE, 127, Short.MAX_VALUE)
										.addGap(122)
										.addComponent(btnLogin, GroupLayout.DEFAULT_SIZE, 127, Short.MAX_VALUE)))
						.addContainerGap()));
		groupLayout.setVerticalGroup(groupLayout.createParallelGroup(Alignment.LEADING).addGroup(groupLayout
				.createSequentialGroup().addContainerGap()
				.addComponent(lblTitle, GroupLayout.PREFERRED_SIZE, 35, GroupLayout.PREFERRED_SIZE)
				.addPreferredGap(ComponentPlacement.RELATED)
				.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
						.addComponent(lblUserName, GroupLayout.PREFERRED_SIZE, 28, GroupLayout.PREFERRED_SIZE)
						.addComponent(textFieldUserName, GroupLayout.PREFERRED_SIZE, 28, GroupLayout.PREFERRED_SIZE))
				.addGap(18)
				.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
						.addComponent(lblPassword, GroupLayout.PREFERRED_SIZE, 29, GroupLayout.PREFERRED_SIZE)
						.addComponent(passwordField, GroupLayout.PREFERRED_SIZE, 29, GroupLayout.PREFERRED_SIZE))
				.addGap(18)
				.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
						.addComponent(btnClear, GroupLayout.PREFERRED_SIZE, 34, GroupLayout.PREFERRED_SIZE)
						.addComponent(btnLogin, GroupLayout.PREFERRED_SIZE, 34, GroupLayout.PREFERRED_SIZE))
				.addGap(68)));
		getContentPane().setLayout(groupLayout);
	}

	private void clear() {
		textFieldUserName.setText("");
		passwordField.setText("");
		textFieldUserName.grabFocus();
	}

	private void login() {
		String username = textFieldUserName.getText();// 用户名
		String password = new String(passwordField.getPassword());// 密码

		// 判断用户名或密码是否为空
		if (username.isBlank() || password.isBlank()) {
			SwingUtilities.invokeLater(
					() -> JOptionPane.showMessageDialog(this, "用户名或密码不能为空", "提示信息", JOptionPane.INFORMATION_MESSAGE));
			textFieldUserName.grabFocus();
			return;
		}

		// 判断用户名是否过长
		if (username.length() > 15) {
			SwingUtilities.invokeLater(
					() -> JOptionPane.showMessageDialog(this, "用户名过长", "提示信息", JOptionPane.INFORMATION_MESSAGE));
			textFieldUserName.setText("");
			textFieldUserName.grabFocus();
			return;
		}

		// 判断密码是否超过限制范围
		if (password.length() < 6 || password.length() > 12) {
			SwingUtilities.invokeLater(
					() -> JOptionPane.showMessageDialog(this, "密码长度范围为6-12", "提示信息", JOptionPane.INFORMATION_MESSAGE));
			passwordField.setText("");
			passwordField.grabFocus();
			return;
		}

		try {
			// 从配置文件获取数据库连接
			Jdbc.getConnection();

			String sql = "select * from user where name = ?";
			// 获取查询结果
			List<Map<String, Object>> list = Jdbc.query(sql, username);
			// 关闭连接
			Jdbc.closeConnection();

			// 查询结果不为空
			if (!list.isEmpty()) {
				Map<String, Object> queryUser = list.get(0);

				// 判断用户名，密码是否正确
				if (username.equals(queryUser.get("name")) && password.equals(queryUser.get("password"))) {
					try {
						this.dispose();// 销毁登录框

						// 建立和服务器的联系
//						Socket socket = new Socket("127.0.0.1", 8080);
						Socket socket = new Socket("localhost", 8080);
//						Socket socket = new Socket("192.168.0.104", 8080);

						// 封装信息
						User user = new User(username, queryUser.get("nickname").toString(), password, socket);

						EventQueue.invokeLater(() -> {
							ChatView chatView = null;
							try {
								chatView = new ChatView(user);// 创建聊天窗口

								new ClientSendThread(user, chatView).start();// 开启发送线程
								ClientSendThread.clientConServer(user);// 传输登录信息
								new ClientReceiveThread(user, chatView).start();// 开启接收线程

							} catch (UnsupportedEncodingException e) {
								SwingUtilities.invokeLater(() -> {
									int result = JOptionPane.showOptionDialog(this, "消息加密错误", "错误",
											JOptionPane.DEFAULT_OPTION, JOptionPane.ERROR_MESSAGE, null, null, null);
									if (result == JOptionPane.OK_OPTION || result == JOptionPane.CLOSED_OPTION) {
										System.exit(1);
									}
								});
							} catch (IOException e) {
								SwingUtilities.invokeLater(() -> {
									int result = JOptionPane.showOptionDialog(this, "创建socket输入输出流出错！", "错误",
											JOptionPane.DEFAULT_OPTION, JOptionPane.ERROR_MESSAGE, null, null, null);
									if (result == JOptionPane.OK_OPTION || result == JOptionPane.CLOSED_OPTION) {
										System.exit(1);
									}
								});
							}
						});
					} catch (UnknownHostException e) {
						SwingUtilities.invokeLater(() -> {
							int result = JOptionPane.showOptionDialog(this, "未知IP地址", "错误", JOptionPane.DEFAULT_OPTION,
									JOptionPane.ERROR_MESSAGE, null, null, null);
							if (result == JOptionPane.OK_OPTION || result == JOptionPane.CLOSED_OPTION) {
								System.exit(1);
							}
						});
					} catch (IOException e) {
						SwingUtilities.invokeLater(() -> {
							int result = JOptionPane.showOptionDialog(this, "连接服务器失败！\n可能网络原因", "错误",
									JOptionPane.DEFAULT_OPTION, JOptionPane.ERROR_MESSAGE, null, null, null);
							if (result == JOptionPane.OK_OPTION || result == JOptionPane.CLOSED_OPTION) {
								System.exit(1);
							}
						});
					}
				} else {
					SwingUtilities.invokeLater(() -> JOptionPane.showMessageDialog(this, "账号或密码错误，请重新输入！", "提示",
							JOptionPane.WARNING_MESSAGE));
					clear();
				}
			} else {
				int result = JOptionPane.showConfirmDialog(this, "未查找到该用户。\n请先注册", "是否注册？？？",
						JOptionPane.OK_CANCEL_OPTION, JOptionPane.INFORMATION_MESSAGE);

				// 用户同意注册
				if (result == JOptionPane.OK_OPTION) {
					this.dispose();// 销毁登录框
					EventQueue.invokeLater(() -> {
						new RegisterView(username, password);// 创建注册窗体
					});
				} else {
					clear();
				}
			}
		} catch (IOException e) {
			SwingUtilities.invokeLater(() -> {
				int result = JOptionPane.showOptionDialog(this, "加载配置信息出错！", "错误消息", JOptionPane.DEFAULT_OPTION,
						JOptionPane.ERROR_MESSAGE, null, null, null);
				if (result == JOptionPane.OK_OPTION || result == JOptionPane.CLOSED_OPTION) {
					System.exit(1);
				}
			});
		} catch (ClassNotFoundException e) {
			SwingUtilities.invokeLater(() -> {
				int result = JOptionPane.showOptionDialog(this, "驱动类未找到！", "错误消息", JOptionPane.DEFAULT_OPTION,
						JOptionPane.ERROR_MESSAGE, null, null, null);
				if (result == JOptionPane.OK_OPTION || result == JOptionPane.CLOSED_OPTION) {
					System.exit(1);
				}
			});
		} catch (SQLException e) {
			SwingUtilities.invokeLater(() -> {
				int result = JOptionPane.showOptionDialog(this, "获取数据库连接失败！\n可能是用户名或密码错误", "错误消息",
						JOptionPane.DEFAULT_OPTION, JOptionPane.ERROR_MESSAGE, null, null, null);
				if (result == JOptionPane.OK_OPTION || result == JOptionPane.CLOSED_OPTION) {
					System.exit(1);
				}
			});
		}
	}
}
